/**
 * @Author: 宋计民
 * @Date: 2022/11/3
 * @Version: 1.0
 * @Content: 从树中向下递归查找
 */

interface TreeNode {
  id: string
  name: string
  children: Array<TreeNode>
  [propName: string]: any
}

interface Opt {
  keyField: string
  [propName: string]: any
}

interface TreeData {
  parent: TreeNode | null
  current: TreeNode
  index: number
}

export function queryDataFromTreeById(
  nodes: Array<TreeNode>,
  id: string,
  parent: TreeNode | null = null,
  opt: Opt = {
    keyField: 'id'
  }
): TreeData | null {
  if (!nodes) {
    return null
  }
  for (let i = 0; i < nodes.length; ++i) {
    const child = nodes[i]
    if (child[opt.keyField] === id) {
      return {
        parent,
        current: child,
        index: i
      }
    }
    if (child?.children?.length) {
      const res = queryDataFromTreeById(child.children, id, child, opt)
      if (res) {
        return res
      }
    }
  }
  return null
}

export function queryDataByField(
  field: string | Function = 'id',
  childrenField = 'children'
) {
  function queryFn(
    nodes: Array<TreeNode>,
    id: string,
    parent: TreeNode | null = null
  ): TreeData | null {
    if (!nodes) {
      return null
    }
    for (let i = 0; i < nodes.length; ++i) {
      const child = nodes[i]
      if (typeof field === 'string' && child[field] === id) {
        return {
          parent,
          current: child,
          index: i
        }
      }
      if (typeof field === 'function' && field?.(child)) {
        return {
          parent,
          current: child,
          index: i
        }
      }
      if (child?.[childrenField]?.length) {
        const res = queryFn(child[childrenField], id, child)
        if (res) {
          return res
        }
      }
    }
    return null
  }
  return (nodes: Array<TreeNode>, id: string) => queryFn(nodes, id)
}
